#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/time.h>

#define ITERATIONS 100000  // 循环次数

// 用于计算时间差
long long get_time_diff(struct timeval start, struct timeval end) {
    return (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_usec - start.tv_usec);
}

int main() {
    int pipe_fd[2], pipe_fd2[2];  // 管道文件描述符
    pid_t pid;
    struct timeval start_time, end_time;
    long long total_time = 0;
    int ret;
    // 创建管道
    if (pipe(pipe_fd) == -1) {
        perror("pipe failed");
        exit(1);
    }
        // 创建管道
    if (pipe(pipe_fd2) == -1) {
        perror("pipe failed");
        exit(1);
    }

    // 创建子进程
    pid = fork();
    if (pid == -1) {
        perror("fork failed");
        exit(1);
    }

    if (pid > 0) {
        // 父进程
        close(pipe_fd[0]);  // 关闭读取端
	close(pipe_fd2[1]);
	printf("1\n");
        for (int i = 0; i < ITERATIONS; i++) {
            // 记录当前时间
            gettimeofday(&start_time, NULL);

            // 向管道写入数据，唤醒子进程
            write(pipe_fd[1], "start", 5);
            // 等待子进程的唤醒信号
            char buf[5];
            ret = read(pipe_fd2[0], buf, 5);
            // 记录时间
            gettimeofday(&end_time, NULL);
            total_time += get_time_diff(start_time, end_time);
        }

        // 输出进程切换时间指标
        printf("Total context switch time (microseconds): %lld\n", total_time);
        printf("Average context switch time: %lld microseconds\n", total_time / (ITERATIONS * 2));

        close(pipe_fd[1]);
	close(pipe_fd2[0]);
        wait(NULL);  // 等待子进程退出
    } else {
        // 子进程
      close(pipe_fd[1]);  // 关闭写入端
      close(pipe_fd2[0]);
 printf("2\n");
        for (int i = 0; i < ITERATIONS; i++) {
            // 等待父进程的唤醒信号
            char buf[5];
            read(pipe_fd[0], buf, 5);
            // 向管道写入数据，唤醒父进程
            write(pipe_fd2[1], "start", 5);
        }

        close(pipe_fd[0]);
	close(pipe_fd2[1]);
        exit(0);  // 子进程结束
    }

    return 0;
}

